package edu.xhu.homepage.util;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import edu.xhu.api.behavior.BehaviorClient;
import edu.xhu.common.exception.CustomException;
import edu.xhu.model.behavior.dto.SonCommentDto;
import edu.xhu.model.behavior.pojos.BiliUserComment;
import edu.xhu.model.behavior.vo.CommentTree;
import edu.xhu.model.common.dtos.ResponseResult;
import edu.xhu.model.common.enums.AppHttpCodeEnum;
import org.springframework.beans.BeanUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 植树节来了
 */
public class TreeBuilder {


    public static Map<String, List<CommentTree>> buildTree(List<Map> root, BehaviorClient behaviorClient) {
        Map<String, CommentTree> result = new HashMap<>();                  //一个根评论
        Map<String, List<CommentTree>> all = new HashMap<>();              //所有视频评论
        List<CommentTree> cache = new ArrayList<>();                       //缓冲队列
        List<Long> commentIds = new ArrayList<>();                          //记录根id
        Map<String, String> Ids = new HashMap<>();                          //记录视频id
        //1.构建根
        for (Map map : root) {
            CommentTree commentTree = new CommentTree();
            //map就是一个根评论对象,先转换
            BiliUserComment comment = JSONUtil.toBean(JSONUtil.toJsonStr(map), BiliUserComment.class);
            BeanUtils.copyProperties(comment, commentTree);
            //放到result里面
            result.put(commentTree.getCommentId().toString(), commentTree);
            //记录CommentId
            commentIds.add(commentTree.getCommentId());
            //记录视频Id
            Ids.put(commentTree.getVideoId().toString(), null);
        }
        //2.查询根的所有子评d
        SonCommentDto hotCommentSonDto = new SonCommentDto();
//        hotCommentSonDto.setCommentIds(commentIds).setLoveWeight(0.65).setCommentWeight(0.35);
        ResponseResult<?> sonRes = behaviorClient.querySonCommentsByRootIds(hotCommentSonDto);
        if (!sonRes.getCode().equals(200)) {
            throw new CustomException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        JSONArray sonArray = JSONUtil.parseArray(sonRes.getData());
        List<Map> sonList = JSONUtil.toList(sonArray, Map.class);
        commentIds = null;
        //3.根据videoIds,初始化all
        List<Long> longs = Ids.keySet().stream().map(Long::parseLong).collect(Collectors.toList());
        for (Long id : longs) {
            all.put(id.toString(), new ArrayList<>());
        }
        longs = null;
        //4.构建子
        int maxDeep = 1;    //记录一下最大深度
        for (Map map : sonList) {
            CommentTree commentTree = new CommentTree();
            //map就是一个评论对象,先转换
            BiliUserComment comment = JSONUtil.toBean(JSONUtil.toJsonStr(map), BiliUserComment.class);
            BeanUtils.copyProperties(comment, commentTree);
            //先去找result中有没有
            if (result.get(commentTree.getParentId().toString()) != null) {
                //如果result中有他的父评论,把这条评论,加到他的父评论的replies中
                result.get(commentTree.getParentId().toString()).getReplies().add(commentTree);
            } else {
                //2.2如果没有他的父评论,但这又是子评论,怎么办,加入到缓冲队列
                cache.add(commentTree);
            }
            //3.遍历完了这个map,可以保证他加入到了评论树吗？不能保证,当前子评论可能暂时还没有父评论！
            //但是可以保证,所有的根评论,都加入到了评论树
            maxDeep = Math.max(maxDeep, commentTree.getDeep());
        }
        sonList = null;
        sonArray = null;
        //如果缓冲队列不为空,遍历直到cache不为空(一级评论,二级评论,三级评论,四级评论,......)
        //问题,孤儿评论???脏数据导致死循环,怎么办?答:评论深度
        int count = 0;
        while (!cache.isEmpty()) {
            count++;    //最少都是一级评论
            //循环次数已经大于最大深度了,表明该评论有问题,跳出循环,不再遍历
            if (count > maxDeep) {
                break;
            }
            List<CommentTree> cTree = new ArrayList<>();
            for (CommentTree tree : cache) {
                //1.判断result中有没有父评论
                if (result.get(tree.getParentId().toString()) != null) {
                    //如果有
                    result.get(tree.getParentId().toString()).getReplies().add(tree);
                    cTree.add(tree);
                } else {
                    //如果没有,继续加入到缓冲中
                    cache.add(tree);
                }
            }
            cache.removeAll(cTree);
        }
        //result是900个根,对吧,现在把他分类,装到每个视频里面
        ArrayList<CommentTree> commentTrees = new ArrayList<>(result.values());
        result = null;
        for (CommentTree commentTree : commentTrees) {
            String id = commentTree.getVideoId().toString();
            if (all.containsKey(id)) {
                List<CommentTree> idTree = all.get(id);
                idTree.add(commentTree);
                all.put(id, idTree);
            } else {
                throw new CustomException(AppHttpCodeEnum.DATA_PATTERN_ERROR);
            }
        }
        return all;
    }

}
